package com.efast.cafe.portal.service.api.impl;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;


import java.util.Date;
import java.util.List;
import java.util.UUID;

import com.efast.cafe.framework.exception.ServiceException;
import com.efast.cafe.framework.util.SpringWebUtils;
import com.efast.cafe.framework.util.SqlFormateUtil;
import com.efast.cafe.portal.bean.api.PortalApiModuleBean;
import com.efast.cafe.portal.bean.api.PortalApiObjectBean;
import com.efast.cafe.portal.bean.api.PortalApiProjectDto;
import com.efast.cafe.portal.bean.api.PortalApiServiceBean;
import com.efast.cafe.portal.bean.query.QueryBean;
import com.efast.cafe.portal.bean.query.TemplateObjBean;
import com.efast.cafe.portal.dao.api.PortalApiFieldDao;
import com.efast.cafe.portal.dao.api.PortalApiModObjDefDao;
import com.efast.cafe.portal.dao.api.PortalApiModServiceDefDao;
import com.efast.cafe.portal.dao.api.PortalApiModuleDao;
import com.efast.cafe.portal.dao.api.PortalApiObjectDao;
import com.efast.cafe.portal.dao.api.PortalApiProSysDefDao;
import com.efast.cafe.portal.dao.api.PortalApiProjectDao;
import com.efast.cafe.portal.dao.api.PortalApiServiceDao;
import com.efast.cafe.portal.dao.api.PortalApiSysModDefDao;
import com.efast.cafe.portal.dao.api.PortalApiSystemDao;
import com.efast.cafe.portal.dao.api.PortalApiViewDao;
import com.efast.cafe.portal.dao.query.QueryTemplateDao;
import com.efast.cafe.portal.entity.query.Template;
import com.efast.cafe.portal.service.api.IPortalApiModuleService;
import com.efast.cafe.portal.service.api.IPortalApiServiceService;
import com.efast.cafe.portal.service.query.IQueryTemplateService;
import com.efast.cafe.util.StringUtil;

import org.springframework.beans.factory.annotation.Autowired;


/**
 * <p>Service接口实现类</p>
 * <p>Table: portal_api_module - 所属模块定义</p>
 *
 * @since 2017-08-10 02:38:08
 */
@Service
@Transactional
public class PortalApiModuleServiceImpl implements IPortalApiModuleService{

	private PortalApiModuleDao portalApiModuleDao;
	
	private PortalApiSysModDefDao portalApiSysModefDao;
	
	private PortalApiModServiceDefDao portalApiModServiceDefDao;
	
	private PortalApiModObjDefDao portalApiModObjDefDao;
	
	private PortalApiObjectDao portalApiObjectDao;
	
	private PortalApiServiceDao portalApiServiceDao;
	
	private PortalApiFieldDao portalApiFieldDao;
	@Autowired
	private IPortalApiServiceService portalApiServiceService;
	
	private PortalApiSystemDao portalApiSystemDao;
	
	private PortalApiProSysDefDao portalApiProSysDefDao;
	
	private PortalApiSysModDefDao portalApiSysModDefDao;
	
	private PortalApiProjectDao portalApiProjectDao;
	
	private QueryTemplateDao queryTemplateDao;
	@Autowired
	private PortalApiViewDao portalApiViewDao;
	
	@Autowired
	private IQueryTemplateService queryTemplateService;
	
	@Autowired
	public void setPortalApiModuleDao(PortalApiModuleDao portalApiModuleDao) {
		this.portalApiModuleDao = portalApiModuleDao;
	}
	
	
	@Autowired
	public void setPortalApiSysModefDao(PortalApiSysModDefDao portalApiSysModefDao) {
		this.portalApiSysModefDao = portalApiSysModefDao;
	}

	
	@Autowired
	public void setPortalApiModServiceDefDao(PortalApiModServiceDefDao portalApiModServiceDefDao) {
		this.portalApiModServiceDefDao = portalApiModServiceDefDao;
	}

	
	@Autowired
	public void setPortalApiModObjDefDao(PortalApiModObjDefDao portalApiModObjDefDao) {
		this.portalApiModObjDefDao = portalApiModObjDefDao;
	}


	@Autowired
	public void setPortalApiObjectDao(PortalApiObjectDao portalApiObjectDao) {
		this.portalApiObjectDao = portalApiObjectDao;
	}


	@Autowired
	public void setPortalApiServiceDao(PortalApiServiceDao portalApiServiceDao) {
		this.portalApiServiceDao = portalApiServiceDao;
	}

	
	@Autowired
	public void setPortalApiFieldDao(PortalApiFieldDao portalApiFieldDao) {
		this.portalApiFieldDao = portalApiFieldDao;
	}

	
	

	
	@Autowired
	public void setPortalApiSystemDao(PortalApiSystemDao portalApiSystemDao) {
		this.portalApiSystemDao = portalApiSystemDao;
	}

	@Autowired
	public void setPortalApiProSysDefDao(PortalApiProSysDefDao portalApiProSysDefDao) {
		this.portalApiProSysDefDao = portalApiProSysDefDao;
	}

	@Autowired
	public void setPortalApiSysModDefDao(PortalApiSysModDefDao portalApiSysModDefDao) {
		this.portalApiSysModDefDao = portalApiSysModDefDao;
	}

	@Autowired
	public void setPortalApiProjectDao(PortalApiProjectDao portalApiProjectDao) {
		this.portalApiProjectDao = portalApiProjectDao;
	}

	
	@Autowired
	public void setQueryTemplateDao(QueryTemplateDao queryTemplateDao) {
		this.queryTemplateDao = queryTemplateDao;
	}


	/**
	 * 新增module
	 * {@inheritDoc} 
	 * overridden:
	 * @Date        :      2017年8月11日
	 * @see com.efast.cafe.portal.remote.api.PortalApiModuleService#insertApiModule(com.efast.cafe.portal.bean.api.PortalApiModuleBean)
	*
	 */
	@Override
	public int insertApiModule(PortalApiModuleBean portalApiModuleBean) {
		apiModuleBeanCheck(portalApiModuleBean);
		int count = portalApiModuleDao.moduleVersionIsExistWhenInsert(portalApiModuleBean);
		if(count!=0){
			throw new ServiceException("版本重复，请重新输入版本");
		}
		int moduleIndentifierCount = portalApiModuleDao.moduleIndentifierCount(portalApiModuleBean);
		if(moduleIndentifierCount!=0){
			throw new ServiceException("系统标识符重复，请重新输入系统标识符");
		}
		//生成uuid
		portalApiModuleBean.setStatus((byte)2);
		portalApiModuleBean.setUuid(UUID.randomUUID().toString());
		portalApiModuleDao.insertApiModule(portalApiModuleBean);
		portalApiSysModefDao.insertApiSysModDef(portalApiModuleBean.getSystemId(),portalApiModuleBean.getId(),SpringWebUtils.getRequestUser(),0);
		return portalApiModuleBean.getId();
	}

	/**
	 * 修改模块
	 * {@inheritDoc} 
	 * overridden:
	 * @Date        :      2017年8月11日
	 * @see com.efast.cafe.portal.remote.api.PortalApiModuleService#updateApiModule(com.efast.cafe.portal.bean.api.PortalApiModuleBean)
	*
	 */
	@Override
	public void updateApiModule(PortalApiModuleBean portalApiModuleBean) {
		//apiModuleBeanCheck(portalApiModuleBean);
		int count = portalApiModuleDao.moduleVersionIsExistWhenUpdate(portalApiModuleBean);
		if(count != 0 ){
			throw new ServiceException("存在相同版本，请修改版本");
		}
		portalApiModuleDao.updateApiModule(portalApiModuleBean);
	}

	/**
	 * 删除模块
	 * {@inheritDoc} 
	 * overridden:
	 * @Date        :      2017年8月11日
	 * @see com.efast.cafe.portal.remote.api.PortalApiModuleService#deleteApiModuledefine(com.efast.cafe.portal.bean.api.PortalApiModuleBean)
	*
	 */
	@Override
	public void deleteApiModule(PortalApiModuleBean portalApiModuleBean) {
		
		//判断该模块下是否有有效Object或者service
		int objCount = portalApiModuleDao.objCountByModuleId(portalApiModuleBean.getId());
		int serviceCount  = portalApiModServiceDefDao.serviceCountByModuleId(portalApiModuleBean.getId());
		if(objCount != 0 || serviceCount !=0){
			throw new ServiceException("该模块存在有效的对象或者服务，不能删除");
		}
		portalApiModuleDao.deleteApiModule(portalApiModuleBean);
		portalApiSysModefDao.deleteApiSysModDef(portalApiModuleBean.getId());
	}

	
	/**
	 * 发布ApiModule
	 * {@inheritDoc} 
	 * overridden:
	 * @Date        :      2017年8月14日
	 * @see com.efast.cafe.portal.remote.api.PortalApiModuleService#publishApiModule(com.efast.cafe.portal.bean.api.PortalApiModuleBean)
	*
	 */
	@Override
	public int publishApiModule(PortalApiModuleBean portalApiModuleBean) {
		if(portalApiModuleBean.getVersion()==null){
			throw new ServiceException("请输入版本号");
		}
		if(portalApiModuleBean.getObjIds()==null){
			throw new ServiceException("请选择需要发布的对象");
		}
		
		if(portalApiModuleBean.getServIds()==null){
			throw new ServiceException("请选择需要发布的服务");
		}
		
		if(portalApiModuleBean.getTemplateIds()==null){
			throw new ServiceException("请选择需要发布的SQL Template");
		}
		portalApiModuleBean.setCreateUser(SpringWebUtils.getRequestUser());
		int count = portalApiModuleDao.moduleVersionIsExistWhenInsert(portalApiModuleBean);
		if(count != 0 ){
			throw new ServiceException("存在相同版本，请修改版本");
		}
		if(portalApiModuleBean.getStatus()!=2){
			portalApiModuleBean.setPublishTime(new Date());
		}
		Integer oldModuleId=portalApiModuleBean.getModuleId();
		//发布模块的时候，相当于复制模块
		portalApiModuleDao.upgradeApiModule(portalApiModuleBean);
		//状态为2的时候，为升级，不需要此处复制关系
		if(portalApiModuleBean.getStatus()!=2){
			//清楚旧模块与系统的关系
			//portalApiSysModefDao.updateIsDefault(portalApiModuleBean.getSystemId(), portalApiModuleBean.getModuleId(), 1,SpringWebUtils.getRequestUser());
			//复制模块跟系统的关系
			portalApiSysModefDao.insertApiSysModDef(portalApiModuleBean.getSystemId(),portalApiModuleBean.getId(),SpringWebUtils.getRequestUser(),1);
		}
		for (int i = 0; i < portalApiModuleBean.getObjIds().size(); i++) {
			PortalApiObjectBean apiObjectBean = new PortalApiObjectBean();
			apiObjectBean.setObjId(portalApiModuleBean.getObjIds().get(i));
			apiObjectBean.setCreateUser(SpringWebUtils.getRequestUser());
			// 复制模块所属的对象信息
			portalApiObjectDao.insertObjectById(apiObjectBean);
			// 复制新模块与对象信息
			portalApiModObjDefDao.insertApiModObjDef(portalApiModuleBean.getId(), apiObjectBean.getId(),SpringWebUtils.getRequestUser());
			// 复制对象字段
			portalApiFieldDao.insertApiFieldByObjId(apiObjectBean.getId(), portalApiModuleBean.getObjIds().get(i),SpringWebUtils.getRequestUser());
		}
		// 复制模块与服务的关系
		for (int i = 0; i < portalApiModuleBean.getServIds().size(); i++) {
			PortalApiServiceBean portalApiServiceBean =  portalApiServiceDao.queryPortalApiServiceDetail(portalApiModuleBean.getServIds().get(i));
			portalApiServiceBean.setModuleId(portalApiModuleBean.getId());
			portalApiServiceBean.setParentId(portalApiServiceBean.getId());
			portalApiServiceBean.setParentLastTime(portalApiServiceBean.getLastUpdateTime());
			portalApiServiceService.insertApiService(portalApiServiceBean);
		}
		// TODO Auto-generated method stub
		//复制通用查询
		for (int i = 0; i < portalApiModuleBean.getTemplateIds().size(); i++) {
			TemplateObjBean objBean = queryTemplateService.queryTempalteDetail(portalApiModuleBean.getTemplateIds().get(i),null);
			int queryTemplateId = objBean.getTemplate().getId();
			if(objBean!=null){
				String message = SqlFormateUtil.doValidation(objBean.getTemplate());
				if(portalApiModuleBean.getStatus()!=2){
					objBean.getTemplate().setPublishTime(new Date());
				}else {
					objBean.getTemplate().setPublishTime(null);
				}
				objBean.getTemplate().setParentId(objBean.getTemplate().getId());
				objBean.getTemplate().setParentLastTime(objBean.getTemplate().getLastUpdateTime());
				objBean.getTemplate().setModule(portalApiModuleBean.getId().toString());
				if (SqlFormateUtil.SUCCESS_MESSAGE.equals(message)) {
					//portalApiModuleBean.setContextPath("index/mgr/app");
					String contextPath = getContextPath(portalApiModuleBean.getContextPath());
					Template template = queryTemplateService.addQueryTemplate(objBean.getTemplate(), objBean.getTableViews(), objBean.getTableConditions(),contextPath,portalApiModuleBean.getSystemId());
					
					int templateConditionCount = queryTemplateDao.templateConditionCount(queryTemplateId,SpringWebUtils.getRequestCompany());
					if(templateConditionCount>0){
						queryTemplateDao.templateConditionCopy(template.getId(), template.getCode(),queryTemplateId, SpringWebUtils.getRequestUser(), SpringWebUtils.getRequestCompany());
					}
				}
			}
			
		}
		//升级view
		List<Integer> viewIds=portalApiModuleBean.getViewIds();
		if(viewIds!=null&&!viewIds.isEmpty()){
			portalApiViewDao.copyViewByIds(viewIds, oldModuleId, portalApiModuleBean.getId());
		}
		return portalApiModuleBean.getId();
	}

	
	/**
	 * 升级ApiModule
	 * {@inheritDoc} 
	 * overridden:
	 * @Date        :      2017年8月15日
	 * @see com.efast.cafe.portal.remote.api.PortalApiModuleService#upgradeApiModule(com.efast.cafe.portal.bean.api.PortalApiModuleBean)
	*
	 */
	@Override
	public int upgradeApiModule(PortalApiModuleBean portalApiModuleBean) {
		//Integer oldModuleId = portalApiModuleBean.getModuleId();
		Integer systemStatus = portalApiModuleBean.getSystem().getStatus().intValue();
		Integer projectStatus = portalApiModuleBean.getProject().getStatus().intValue();
		//发布模块的时候，相当于复制模块 ，通过moduleId查询module相关的object
		portalApiModuleBean.setObjIds(portalApiObjectDao.queryObjIds(portalApiModuleBean.getModuleId()));
		//通过moduleId查询module相关的service
		portalApiModuleBean.setServIds(portalApiServiceDao.queryPortalApiServiceIdsByModuleId(portalApiModuleBean.getModuleId()));
		//通过moduleId查询通用查询的idtemplateIds
		portalApiModuleBean.setTemplateIds(queryTemplateDao.selectTemplateIdsByMouduleId(portalApiModuleBean.getModuleId()));
		//设置systemId
		portalApiModuleBean.setSystemId(portalApiModuleBean.getSystem().getSystemId());
		//通过moduleId查询view的id viewIds
		portalApiModuleBean.setViewIds(portalApiViewDao.queryViewIdsByModuleId(portalApiModuleBean.getModuleId()));
		
		//调发布方法复制模块，因为需要复制模块相关的object和service信息
		publishApiModule(portalApiModuleBean);
		//判断系统是否存在，存在生成新的系统
		if(systemStatus==1){
			if(portalApiModuleBean.getSystem().getVersion()==null){
				throw new ServiceException("请输入系统版本号");
			}
			//获取系统id
			Integer systemId = portalApiModuleBean.getSystem().getSystemId();
			portalApiModuleBean.getSystem().setId(systemId);
			portalApiModuleBean.getSystem().setStatus((byte) 2);
			portalApiModuleBean.setCreateUser(SpringWebUtils.getRequestUser());
			//生成新的系统
			portalApiSystemDao.copyApiSystem(portalApiModuleBean.getSystem());
			//新系统id
			Integer newsystemId = portalApiModuleBean.getSystem().getId();
			//复制新模块跟新系统的关系
			portalApiSysModefDao.insertApiSysModDef(newsystemId,portalApiModuleBean.getId(),SpringWebUtils.getRequestUser(),0);
		//系统不存在新的的时候，是否存在新的模块
		}/*else{
			//如果不存在系统，则去掉默认关联，增加新module与系统关系
			portalApiSysModefDao.updateIsDefault(portalApiModuleBean.getSystem().getSystemId(), oldModuleId, 1,SpringWebUtils.getRequestUser());
			// 新增一条新增模块与系统的信息
			portalApiSysModDefDao.insertApiSysModDef(portalApiModuleBean.getSystem().getSystemId(), portalApiModuleBean.getId(), SpringWebUtils.getRequestUser(),1);
			
		}*/
		//判断是否存在project
		if(projectStatus==1){
			if(portalApiModuleBean.getProject().getVersion()==null){
				throw new ServiceException("请输入项目版本号");
			}
			//记录需要升级的ProjectId
			//Integer oldProjectId = portalApiModuleBean.getProject().getId();
			portalApiModuleBean.getProject().setStatus((byte) 2);
			int projectCount = portalApiProjectDao.projectVersionInsert(portalApiModuleBean.getProject());
			if(projectCount!=0){
				throw new ServiceException("已经存在相同版本，请重新输入");
			}
			//升级project
			portalApiProjectDao.upgradeApiProject(portalApiModuleBean.getProject());
			//记录升级后的projectId
			Integer newProjectId = portalApiModuleBean.getProject().getId();
			if(systemStatus==1){
				//系统项目均需要升级,关联新项目新系统的关系
				portalApiProSysDefDao.insertApiProSysDef(newProjectId, portalApiModuleBean.getSystem().getId(), 0,SpringWebUtils.getRequestUser());
			}/*else {
				// 新增一条新增模块与原系统的信息
				portalApiSysModDefDao.insertApiSysModDef(portalApiModuleBean.getSystem().getSystemId(), portalApiModuleBean.getId(), SpringWebUtils.getRequestUser(),0);
				//关联新项目原系统的关系
				portalApiProSysDefDao.insertApiProSysDef(newProjectId, portalApiModuleBean.getSystem().getSystemId(), 0,SpringWebUtils.getRequestUser());
			}*/
		}else {
			//项目不需要升级，系统需要升级
			if(systemStatus==1){
				//取消原系统与项目的默认关系，
				//List<Integer> systemIds = new ArrayList<>();
				//systemIds.add(portalApiModuleBean.getSystem().getSystemId());
				//portalApiProSysDefDao.cleanApiProSysDefaultDef(portalApiModuleBean.getProject().getProjectId(), systemIds, SpringWebUtils.getRequestUser());
				if(portalApiModuleBean.getSystem().getVersion()==null){
					throw new ServiceException("请输入系统版本号");
				}
				//关联原来的项目新系统的关系
				portalApiProSysDefDao.insertApiProSysDef(portalApiModuleBean.getProject().getProjectId(), portalApiModuleBean.getSystem().getId(), 1,SpringWebUtils.getRequestUser());
			}else{
				//项目系统都不需要升级,则去掉默认关联，增加新module与系统关系
				//portalApiSysModefDao.updateIsDefault(portalApiModuleBean.getSystem().getSystemId(), oldModuleId, 1,SpringWebUtils.getRequestUser());
				// 新增一条新增模块与系统的信息
				portalApiSysModDefDao.insertApiSysModDef(portalApiModuleBean.getSystem().getSystemId(), portalApiModuleBean.getId(), SpringWebUtils.getRequestUser(),1);
			}
		}
		//view升级
		
		return portalApiModuleBean.getId();
	}

	/**
	 * 查询同一个系统底下，某个module的所有版本
	 * {@inheritDoc} 
	 * overridden:
	 * @Date        :      2017年8月24日
	 * @see com.efast.cafe.portal.remote.api.PortalApiModuleService#queryModuleBySystemIdAndUUid(com.efast.cafe.portal.bean.api.PortalApiModuleBean)
	 *
	 */
	public List<PortalApiModuleBean> queryModuleBySystemIdAndUUid(PortalApiModuleBean apiModuleBean) {
		return portalApiModuleDao.queryModuleBySystemIdAndUUid(apiModuleBean);
	}


	/**
	 * 通过system查询该系统底下所有最新的模块
	 * {@inheritDoc} 
	 * overridden:
	 * @Date        :      2017年8月26日
	 * @see com.efast.cafe.portal.remote.api.PortalApiModuleService#queryModuleBySystemId(com.efast.cafe.portal.bean.api.PortalApiProjectDto)
	*
	 */
	@Override
	public List<PortalApiModuleBean> queryModuleBySystemId(PortalApiProjectDto portalApiProjectDto) {
		portalApiProjectDto.setId(portalApiProjectDto.getSystemId());
		return portalApiModuleDao.treeApiModuleBySystemId(portalApiProjectDto);
	}
	
	/**
	 * 基础校验
	 * @Date        :      2017年9月1日
	 * @param apiModuleBean
	 */
	public void apiModuleBeanCheck(PortalApiModuleBean apiModuleBean){
		if(apiModuleBean.getModuleName().isEmpty() || apiModuleBean.getVersion().isEmpty() || apiModuleBean.getIndentifier().isEmpty()){
			throw new ServiceException("项目名称、版本、标识符不能为空！");
		}
		if (!apiModuleBean.getModuleUri().startsWith("/")) {
			throw new ServiceException("模块路径格式不正确！");
		}
	}
	
	
	private String getContextPath(String contextPath) {
		if (contextPath == null || StringUtil.isEmpty(contextPath)) {
			return null;
		}
		String [] param = contextPath.split("/");
		String newContextPath = "";
		if (param.length > 2) {
			newContextPath = param[1]+param[2];
		}
		
		return newContextPath;
	}
}